﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.ComponentModel;
using System.IO.IsolatedStorage;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Runtime.Serialization;

namespace Curling
{
    [DataContractAttribute]
    public class Score : INotifyPropertyChanged
    {
        [DataMemberAttribute]
        public Player Player1 { get; set; }
        [DataMemberAttribute]
        public Player Player2 { get; set; }

        [DataMemberAttribute]
        public int?[][] Scores { get; set; }

        [DataMemberAttribute]
        public int CurrentRound { get; set; }

        public int FinalScore1
        {
            get
            {
                int Sum = 0;

                for (int i = 0; i < Scores[0].Length; i++)
                {
                    Sum += (Scores[0][i].HasValue) ? Scores[0][i].Value : 0;
                }

                return Sum;
            }
        }

        public int FinalScore2
        {
            get
            {
                int Sum = 0;

                for (int i = 0; i < Scores[1].Length; i++)
                {
                    Sum += (Scores[1][i].HasValue) ? Scores[1][i].Value : 0;
                }

                return Sum;
            }
        }

        public Score(Player Player1, Player Player2)
        {
            Scores = new int?[][] {new int?[10], new int?[10]};

            this.Player1 = Player1;
            this.Player2 = Player2;
        }

        public void Reset()
        {
            Scores = new int?[][] { new int?[10], new int?[10] };

            CurrentRound = 0;

            FirePropertyChangedEvent("Scores");
            FirePropertyChangedEvent("FinalScore1");
            FirePropertyChangedEvent("FinalScore2");
        }

        public void AddRoundResult(int Player1Score, int Player2Score)
        {
            Scores[0][CurrentRound] = Player1Score;
            Scores[1][CurrentRound] = Player2Score;

            IsolatedStorageSettings settings = IsolatedStorageSettings.ApplicationSettings;

            int Score = Math.Max(Player1Score, Player2Score);
            string Player1Name = (Player1Score >= Player2Score) ? Player1.Name : Player2.Name;
            string Player2Name = (Player1Score >= Player2Score) ? Player2.Name : Player1.Name;

            CurrentRound++;

            bool Added = false;

            if (CurrentRound == 10)
            {
                if (!settings.Contains("MatchesScoreTable"))
                    settings["MatchesScoreTable"] = new ObservableCollection<ScoreTableItem>();

                ObservableCollection<ScoreTableItem> MatchesScoreTable = (ObservableCollection<ScoreTableItem>)settings["MatchesScoreTable"];

                int MatchScore = Math.Max(FinalScore1, FinalScore2) - Math.Min(FinalScore1, FinalScore2);
                Player1Name = (FinalScore1 >= FinalScore2) ? Player1.Name : Player2.Name;
                Player2Name = (FinalScore1 >= FinalScore2) ? Player2.Name : Player1.Name;

                Added = false;

                for (int i = 0; i < MatchesScoreTable.Count; i++)
                {
                    if (MatchScore > MatchesScoreTable[i].score1 - MatchesScoreTable[i].score2)
                    {
                        MatchesScoreTable.Insert(i, new ScoreTableItem() { Player1 = Player1Name, Player2 = Player2Name, score1 = Math.Max(FinalScore1, FinalScore2), score2 = Math.Min(FinalScore1, FinalScore2) });
                        Added = true;
                        break;
                    }
                }

                if (!Added)
                {
                    MatchesScoreTable.Add(new ScoreTableItem() { Player1 = Player1Name, Player2 = Player2Name, score1 = Math.Max(FinalScore1, FinalScore2), score2 = Math.Min(FinalScore1, FinalScore2) });
                }

                if (MatchesScoreTable.Count > 10)
                {
                    MatchesScoreTable.RemoveAt(10);
                }
            }

            settings.Save();

            FirePropertyChangedEvent("Scores");
            FirePropertyChangedEvent("FinalScore1");
            FirePropertyChangedEvent("FinalScore2");
        }

        public void SaveGameResult(bool Local)
        {
            if (FinalScore1 > 0 || FinalScore2 > 0)
            {
                IsolatedStorageSettings settings = IsolatedStorageSettings.ApplicationSettings;
                
                int MatchScore = Math.Max(FinalScore1, FinalScore2) - Math.Min(FinalScore1, FinalScore2);
                string Player1Name = (FinalScore1 >= FinalScore2) ? Player1.Name : Player2.Name;
                string Player2Name = (FinalScore1 >= FinalScore2) ? Player2.Name : Player1.Name;

                if (Local)
                {
                    if (!settings.Contains("MatchesScoreTable"))
                        settings["MatchesScoreTable"] = new ObservableCollection<ScoreTableItem>();

                    ObservableCollection<ScoreTableItem> MatchesScoreTable = (ObservableCollection<ScoreTableItem>)settings["MatchesScoreTable"];

                    bool Added = false;

                    for (int i = 0; i < MatchesScoreTable.Count; i++)
                    {
                        if (MatchScore > MatchesScoreTable[i].score1 - MatchesScoreTable[i].score2)
                        {
                            MatchesScoreTable.Insert(i, new ScoreTableItem() { Player1 = Player1Name, Player2 = Player2Name, score1 = Math.Max(FinalScore1, FinalScore2), score2 = Math.Min(FinalScore1, FinalScore2) });
                            Added = true;
                            break;
                        }
                    }

                    if (!Added)
                    {
                        MatchesScoreTable.Add(new ScoreTableItem() { Player1 = Player1Name, Player2 = Player2Name, score1 = Math.Max(FinalScore1, FinalScore2), score2 = Math.Min(FinalScore1, FinalScore2) });
                    }

                    if (MatchesScoreTable.Count > 10)
                    {
                        MatchesScoreTable.RemoveAt(10);
                    }
                }
                else
                {
                    if (!settings.Contains("InternetScoreTable"))
                        settings["InternetScoreTable"] = new ObservableCollection<ScoreTableItem>();

                    ObservableCollection<ScoreTableItem> InternetScoreTable = (ObservableCollection<ScoreTableItem>)settings["InternetScoreTable"];

                    bool Added = false;

                    for (int i = 0; i < InternetScoreTable.Count; i++)
                    {
                        if (MatchScore > InternetScoreTable[i].score1 - InternetScoreTable[i].score2)
                        {
                            InternetScoreTable.Insert(i, new ScoreTableItem() { Player1 = Player1Name, Player2 = Player2Name, score1 = Math.Max(FinalScore1, FinalScore2), score2 = Math.Min(FinalScore1, FinalScore2) });
                            Added = true;
                            break;
                        }
                    }

                    if (!Added)
                    {
                        InternetScoreTable.Add(new ScoreTableItem() { Player1 = Player1Name, Player2 = Player2Name, score1 = Math.Max(FinalScore1, FinalScore2), score2 = Math.Min(FinalScore1, FinalScore2) });
                    }

                    if (InternetScoreTable.Count > 10)
                    {
                        InternetScoreTable.RemoveAt(10);
                    }
                }

                settings.Save();
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        public void FirePropertyChangedEvent(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }
}
